package JVM.第06篇_垃圾回收篇;

/**
 * 内存泄露-8种情况
 *
 * 1-静态集合类
 *      如HashMap、 LinkedList等等。如果这些容器为静态的，
 *      那么它们的生命周期与JVM程序一致，则容器中的对象在程序结束之前将不能被释放，从而造成内存泄漏。
 *      简单而言，长生命周期的对象持有短生命周期对象的引用，尽管短生命周期的对象不再使用，
 *      但是因为长生命周期对象持有它的引用而导致不能被回收。
 * 2-单例模式
 *      和静态集合导致内存泄露的原因类似，因为单例的静态特性，
 *      它的生命周期和JVM的生命周期一样长，所以如果单例对象如果持有外部对象的引用，
 *      那么这个外部对象也不会被回收，那么就会造成内存泄漏。
 * 3-内部类持有外部类
 *      如果一个外部类的实例对象的方法返回了一个内部类的实例对象。
 *      这个内部类对象被长期引用了，即使那个外部类实例对象不再被使用，但由于内部类持有
 *      外部类的实例对象，这个外部类对象将不会被垃圾回收，这也会造成内存泄漏。
 * 4-各种连接，如数据库连接、网络连接和IO连接等
 *      在对数据库进行操作的过程中，首先需要建立与数据库的连接，当不再使用时，需要调用
 *      close方法来释放与数据库的连接。只有连接被关闭后，垃圾回收器才会回收对应的对象。
 *      否则，如果在访问数据库的过程中，对Connection、Statement 或 ResultSet不显性地关闭，
 *      将会造成大量的对象无法被回收，从而引起内存泄漏。
 * 5-变量不合理的作用域
 *      一般而言，一个变量的定义的作用范围大于其使用范围，很有可能会造成内存泄漏。
 *      另一方面，如果没有及时地把对象设置为null,很有可能导致内存泄漏的发生。
 * 6-改变哈希值
 *      改变哈希值，当一个对象被存储进HashSet集合中以后，
 *      就不能修改这个对象中的那些参与计算哈希值的字段了。
 *      否则，对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了，
 *      在这种情况下，即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象
 *      也将返回找不到对象的结果，
 *      这也会导致无法从HashSet集合中单独删除当前对象，造成内存泄漏。
 *      这也是String为什么被设置成了不可变类型，我们可以放心地把String存入
 *      HashSet,或者把String当做HashMap 的key 值;
 *      当我们想把自己定义的类保存到散列表的时候，需要保证对象的hashCode 不可变。
 * 7-缓存泄漏
 *      内存泄漏的另一个常见来源是缓存，一旦你把对象引用放入到缓存中，他就很容易遗忘。
 *      比如:之前项目在一次上线的时候，应用启动奇慢直到夯死，
 *      就是因为代码中会加载一个表中的数据到缓存(内存)中，
 *      测试环境只有几百条数据，但是生产环境有几百万的数据对于这个问题，
 *      可以使用WeakHashMap代表缓存，此种Map的特点是，当除了自身有对key的引用外，
 *      此key没有其他引用那么此map会自动丢弃此值。
 * 8-监听器和回调
 *      内存泄漏另一个常见来源是监听器和其他回调，
 *      如果客户端在你实现的API中注册回调，却没有显式的取消，那么就会积聚。
 *      需要确保回调立即被当作垃圾回收的最佳方法是只保存它的弱引用，
 *      例如将他们保存成为WeakHashMap中的键。
 *
 *
 */
public class F4_内存泄露 {

}
